package com.unionfetch.content_home.ui.fragment

import android.annotation.SuppressLint
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.unionfetch.content_home.R
import com.unionfetch.content_home.bean.AccountCategory
import com.unionfetch.content_home.bean.DemoAccountInfo
import com.unionfetch.content_home.bean.DemoTradeAccount
import com.unionfetch.content_home.bean.LiveAccountInfo
import com.unionfetch.content_home.bean.LiveTradeAccount
import com.unionfetch.content_home.bean.TradeAccountModel
import com.unionfetch.content_home.bean.TradeAccountStatus
import com.unionfetch.content_home.bean.TradeDataDetail
import com.unionfetch.content_home.bean.UserStatus
import com.unionfetch.content_home.bean.UserType
import com.unionfetch.content_home.bean.change2TradeAccountModel
import com.unionfetch.content_home.contract.AccountContract
import com.unionfetch.content_home.contract.HomeContract
import com.unionfetch.content_home.presenter.AccountPresenter
import com.unionfetch.content_home.presenter.HomePresenter
import com.unionfetch.content_home.ui.GuideCreateAccountActivity
import com.unionfetch.content_home.ui.account.AccountManagerActivity
import com.unionfetch.content_home.ui.dialog.SelectTradeAccountDialog
import com.unionfetch.content_home.ui.view.OpenAccountStateView
import com.unionfetch.content_home.ui.view.TradeAccountDetailCardView
import com.unionftech.common.R.string
import com.unionftech.common.base.BaseFragment
import com.unionftech.common.base.IUpdate
import com.unionftech.common.base.mvp.annitation.InjectPresenter
import com.unionftech.common.base.mvp.impl.BaseMvpFragment
import com.unionftech.common.bean.ResponseResult
import com.unionftech.common.bean.toast
import com.unionftech.common.common.GlobalInfoManager
import com.unionftech.common.common.adapter.CommonFragmentStateAdapter
import com.unionftech.common.common.bean.SystemUserInfo
import com.unionftech.common.common.bean.UserKYCFileInfo
import com.unionftech.common.common.contract.CommonContract
import com.unionftech.common.common.language.DynamicResourceManager
import com.unionftech.common.common.presenter.CommonPresenter
import com.unionftech.common.utils.LogUtils
import com.unionftech.common.utils.SpUtils
import com.unionftech.common.utils.ToastUtils
import com.unionftech.common.utils.Utils
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * HomeFragment
 */
class HomeFragment : BaseMvpFragment(), IUpdate, AccountContract.ILiveTradeListView,
    AccountContract.IDemoTradeListView, HomeContract.ITradeDataView, CommonContract.IAccountView,
    CommonContract.IKycInfoView {
    private val mTvCurAccountInfo by lazy { mRootView.findViewById<TextView>(R.id.tv_cur_account_info) }
    private val mIvArrowDown by lazy { mRootView.findViewById<ImageView>(R.id.iv_arrow_down) }
    private val mIvCustomer by lazy { mRootView.findViewById<ImageView>(R.id.iv_customer) }
    private val mOpenAccountStateView by lazy { mRootView.findViewById<OpenAccountStateView>(R.id.open_account_state_view) }
    private val mTradeAccountCardView by lazy { mRootView.findViewById<TradeAccountDetailCardView>(R.id.trade_account_card_view) }
    private val mTabLayout by lazy { mRootView.findViewById<TabLayout>(R.id.tab_layout) }
    private val mViewPager by lazy { mRootView.findViewById<ViewPager2>(R.id.view_pager) }

    @InjectPresenter
    private lateinit var mAccountPresenter: AccountPresenter

    @InjectPresenter
    private lateinit var mHomePresenter: HomePresenter

    @InjectPresenter
    private lateinit var mCommonPresenter: CommonPresenter

    private lateinit var mFragments: List<BaseFragment>
    private lateinit var mTitles: List<String>
    private lateinit var mAdapter: CommonFragmentStateAdapter
    private var mIsShowLoading = false
    private var mKycFileInfo: UserKYCFileInfo? = null
    private var mUserInfo: SystemUserInfo? = null
    private val mAllTradeAccountList = mutableListOf<TradeAccountModel>()
    private var mIsJumpToGuide = false

    //当前账号选中的位置
    private var mCurAccountIndex = -1
    private var mCurUserId: String = ""
    private var mCurTradeNo: String = ""
    private var mCurTradeType: AccountCategory = AccountCategory.LIVE
    private var mIsActive = false
    private var mLiveList: List<LiveTradeAccount>? = null
    private var mDemoList: List<DemoTradeAccount>? = null
    private var mIsShowAccountDialog = false


    companion object {
        private const val TAG = "HomeFragment"

        @JvmStatic
        fun newInstance() = HomeFragment().apply {
            arguments = Bundle().apply {

            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {

        }
    }

    override fun inflaterContentView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun initData() {
        super.initData()
        mTitles = listOf(
            DynamicResourceManager.getString(mContext, string.position),
            DynamicResourceManager.getString(mContext, string.registration),
            DynamicResourceManager.getString(mContext, string.history)
        )
        mFragments = listOf(
            TakePositionFragment.newInstance(),
            TakePositionFragment.newInstance(),
            TakePositionFragment.newInstance()
        )
        mAdapter = CommonFragmentStateAdapter(mActivity)
        mAdapter.addFragment(mFragments)
    }

    override fun setListener() {
        super.setListener()
        GlobalInfoManager.getInstance().addListener(this)
        mTvCurAccountInfo.setOnClickListener(this)
        mIvArrowDown.setOnClickListener(this)
        mIvCustomer.setOnClickListener(this)
        mTradeAccountCardView.setOnClickListener(this)
    }

    override fun loadData() {
        super.loadData()
        mUserInfo = null
        mKycFileInfo = null
        loadUserInfo()
        loadTradeListInfo()
    }

    private fun loadTradeListInfo() {
        val userToken = GlobalInfoManager.getInstance().getUserToken()
        mAccountPresenter.getUserLiveAccountList(userToken)
        mAccountPresenter.getUserDemoAccountList(userToken)
    }

    private fun loadUserInfo() {
        val userToken = GlobalInfoManager.getInstance().getUserToken()
        mCommonPresenter.getOuterUserInfo(userToken)
        mCommonPresenter.getKycInfo(userToken)
    }

    override fun setView() {
        super.setView()
        hideTitleBar()
        setupViewpager()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (!hidden) {
            loadData()
        }
    }

    override fun onResume() {
        super.onResume()
        loadData()
    }

    override fun needShowLoading(): Boolean {
        return mIsShowLoading
    }

    private fun setupViewpager() {
        mViewPager.adapter = mAdapter
        mViewPager.offscreenPageLimit = 1
        mViewPager.setUserInputEnabled(false)
        mViewPager.isSaveEnabled = false
        TabLayoutMediator(mTabLayout, mViewPager) { tab, position ->
            tab.text = mTitles[position]
        }.attach()
    }


    /**
     * 检查跳转开户引导页
     */
    private val gotoCreateAccount = Utils.debounceOnMainThread<SystemUserInfo> { obj ->
        LogUtils.d(
            "HomeFragment", "gotoCreateAccount  mIsJumpToGuide-->${mIsJumpToGuide}"
        )
        if (!mIsJumpToGuide) {
            //跳转开户引导
            gotoGuideCreateAccount(obj)
            mIsJumpToGuide = true
        }
    }

    /**
     * 更新openAccountState
     */
    private fun updateHomeOpenStateView() {
        if (mUserInfo != null && mKycFileInfo != null) {
            //更新头部引导
            mOpenAccountStateView.updateRC(mUserInfo!!, mKycFileInfo!!)
        }
        if (mUserInfo != null && mUserInfo!!.type == UserType.IB.type) {
            mOpenAccountStateView.updateIB(mUserInfo!!)
        }
    }

    /**
     * 获取到真实的账户列表
     */
    override fun handleUserLiveAccountList(result: ResponseResult<LiveAccountInfo>) {
        if (result.code == ResponseResult.SUCCESS_CODE) {
            result.data?.matTradesResps?.also { resps ->
                val list = mutableListOf<LiveTradeAccount>()
                list.addAll(resps.running)
                list.addAll(resps.readOnly)
                list.addAll(resps.disable)
                list.addAll(resps.archived)
                mLiveList = list
                checkAndMerge()
            }
        } else {
            result.toast()
            LogUtils.d(
                TAG, "handleUserLiveAccountList error-->$result"
            )
        }
    }

    private fun checkAndMerge() {
        if (mLiveList != null && mDemoList != null) {
            mAllTradeAccountList.clear()
            mergeLiveAccount(mLiveList!!)
            mergeDemoAccount(mDemoList!!)
            if (mIsShowAccountDialog) {
                hideLoading()
                mIsShowLoading = false
                mIsShowAccountDialog = false
                showSelectAccountDialog()
            } else {
                updateAccountText()
            }
        }
    }

    /**
     * 获取到虚拟账户列表
     */
    override fun handleUserDemoAccountList(result: ResponseResult<DemoAccountInfo>) {
        if (result.code == ResponseResult.SUCCESS_CODE) {
            result.data?.also { info ->
                val list = mutableListOf<DemoTradeAccount>()
                list.addAll(info.enable)
                list.addAll(info.disable)
                mDemoList = list
                checkAndMerge()
            }
        } else {
            result.toast()
            LogUtils.d(
                TAG, "handleUserDemoAccountList error-->$result"
            )
        }
    }

    /**
     * 获取到账户的详细资金数据
     */
    override fun handleTradeDataDetail(response: ResponseResult<TradeDataDetail>) {
        if (response.code == ResponseResult.SUCCESS_CODE) {
            response.data?.also {
                updateTradeDataUI(it)
            }
        } else {
            response.toast()
            LogUtils.d(
                TAG, "handleTradeDataDetail error -> $response"
            )
        }
    }

    override fun handleOuterUserInfoResult(response: ResponseResult<SystemUserInfo>) {
        if (response.code == ResponseResult.SUCCESS_CODE) {
            response.data?.also { systemUserInfo ->
                mUserInfo = systemUserInfo
                mCurUserId = systemUserInfo.userId.toString()
                GlobalInfoManager.getInstance().updateUserInfo(systemUserInfo)
                GlobalInfoManager.getInstance().notifyAll(GlobalInfoManager.UPDATE_VERSION_INFO)
                gotoCreateAccount(systemUserInfo)
                updateHomeOpenStateView()
                checkAndMerge()
            }
        } else {
            response.toast()
            LogUtils.d(
                TAG, "handleOuterUserInfoResult error -> $response"
            )
        }
    }

    /**
     * 获取kyc认证信息，是否需要补料
     */
    override fun handleKycInfoResult(response: ResponseResult<UserKYCFileInfo>) {
        if (response.code == ResponseResult.SUCCESS_CODE) {
            response.data?.also {
                mKycFileInfo = it
                updateHomeOpenStateView()
            }
        } else {
            response.toast()
            LogUtils.d(
                HomeFragment::class.java.simpleName, "handleKycInfoResult error -> $response"
            )
        }
    }

    override fun handleFloatSurplus(response: ResponseResult<String>) {
        if (response.code == ResponseResult.SUCCESS_CODE) {
            val data = response.data
            if (!TextUtils.isEmpty(data)) {
                updateFloatSurplus(data!!)
            }
        } else {
            LogUtils.d(
                HomeFragment::class.java.simpleName, "handleFloatSurplus error -> $response"
            )
        }
    }


    override fun doClick(v: View?) {
        super.doClick(v)
        when (v?.id) {
            R.id.tv_cur_account_info, R.id.iv_arrow_down -> {
                if (TextUtils.isEmpty(mCurTradeNo)) {
                    ToastUtils.longToast(
                        DynamicResourceManager.getString(string.without_trade_account)
                    )
                    return
                }
                //弹出账号选择
                requestAccountAndShowDialog()
            }

            R.id.iv_customer -> {
                //todo:客服正在开发
                ToastUtils.longToast(
                    DynamicResourceManager.getString(
                        mContext, string.developing
                    )
                )
            }

            R.id.trade_account_card_view -> {
                gotoAccountManager()
            }
        }
    }

    private fun requestAccountAndShowDialog() {
        mIsShowLoading = true
        mIsShowAccountDialog = true
        mLiveList = null
        mDemoList = null
        loadTradeListInfo()
    }

    private fun gotoAccountManager() {
        if (mLiveList != null && mLiveList!!.isNotEmpty()) {
            AccountManagerActivity.startThis(mContext, 0, mKycFileInfo)
            return
        }
        if (mDemoList != null && mDemoList!!.isNotEmpty()) {
            AccountManagerActivity.startThis(mContext, 1, mKycFileInfo)
            return
        }
        AccountManagerActivity.startThis(mContext, 0, mKycFileInfo)
    }

    /**
     * 将真实账户的数据列表合并到总的list集合中
     */
    private fun mergeLiveAccount(list: List<LiveTradeAccount>) {
        for (liveTradeAccount in list) {
            val tradeAccountModel = liveTradeAccount.change2TradeAccountModel()
            mAllTradeAccountList.add(tradeAccountModel)
        }
    }

    /**
     * 将虚拟账户的数据列表合并到总的list集合中，要保证真实账户的数据已经合并完成之后在进行此操作
     */
    private fun mergeDemoAccount(demoList: List<DemoTradeAccount>) {
        for (demoTradeAccount in demoList) {
            var accountModel = demoTradeAccount.change2TradeAccountModel()
            if (TextUtils.equals(demoTradeAccount.tradeState.toString(), "1")) {
                //当 tradeState == 1 交易状态为 关闭 status = 3 只读
                accountModel = accountModel.copy(status = TradeAccountStatus.READ_ONLY)
            } else if (TextUtils.equals(demoTradeAccount.loginState, "0")) {
                //当 loginState == 0 登录状态为 关闭 - status = 2 禁用，
                accountModel = accountModel.copy(status = TradeAccountStatus.DISABLE)
            }
            mAllTradeAccountList.add(accountModel)
        }
    }

    /**
     * 弹出选择账户列表
     */
    private fun showSelectAccountDialog() {
        LogUtils.d(
            HomeFragment::class.java.simpleName,
            "showSelectAccountDialog account list-->$mAllTradeAccountList"
        )
        val dialogFragment = SelectTradeAccountDialog(mContext)
        dialogFragment.setData(mAllTradeAccountList)
        dialogFragment.setSelectIndex(mCurAccountIndex)
        dialogFragment.setCallBack { selectIndex ->
            mAllTradeAccountList.getOrNull(selectIndex)?.also {
                //将用户Id与当前显示的交易账号Id，进行字典存储
                SpUtils.getInstance().put(mCurUserId, it.tradeNo)
                mCurAccountIndex = selectIndex
                updateAccountText(mCurAccountIndex)
            }
        }
        dialogFragment.show()
    }

    /**
     * 更新当前交易账号的首页数据
     */
    private fun requestTradeData(category: AccountCategory) {
        val userToken = GlobalInfoManager.getInstance().getUserToken()
        mHomePresenter.getTradeDataDetail(userToken, mCurTradeNo, category)
    }

    /**
     * 每个1秒，查询浮动盈亏
     */
    private fun requestFloatSurplus(category: AccountCategory) {
        lifecycleScope.launch {
            while (mIsActive) { // 协程被取消时自动退出
                val userToken = GlobalInfoManager.getInstance().getUserToken()
                mHomePresenter.getFloatSurplus(
                    userToken, mCurTradeNo, category.type
                )
                delay(1000)
            }
        }
    }

    private fun updateTradeDataUI(detail: TradeDataDetail) {
        mTradeAccountCardView.updateData(detail)
    }

    private fun updateFloatSurplus(floatSurplus: String) {
        mTradeAccountCardView.updateFloatSurplus(floatSurplus)
    }

    /**
     * 更新当前账户id展示
     */
    private fun updateAccountText() {
        if (mCurAccountIndex == -1) {
            //没有选择，则默认展示第一条
            mCurAccountIndex = 0
            //首先判断用户有没有选择
            LogUtils.d("updateAccountText mCurUserId-->${mCurUserId}")
            if (!TextUtils.isEmpty(mCurUserId)) {
                val tradeNo = SpUtils.getInstance().getString(mCurUserId)
                LogUtils.d("updateAccountText tradeNo-->${tradeNo}")
                if (!TextUtils.isEmpty(tradeNo)) {
                    mAllTradeAccountList.forEachIndexed { index, tradeAccountModel ->
                        if (tradeAccountModel.tradeNo == tradeNo) {
                            mCurAccountIndex = index
                        }
                    }
                }
            }
        }
        LogUtils.d("updateAccountText mCurAccountIndex-->${mCurAccountIndex}")
        updateAccountText(mCurAccountIndex)
    }

    @SuppressLint("SetTextI18n")
    private fun updateAccountText(index: Int) {
        mAllTradeAccountList.getOrNull(index)?.also {
            mCurTradeNo = it.tradeNo
            mCurTradeType = it.type
            val startText = it.type.showName
            val accountNo = it.tradeNo
            mTvCurAccountInfo.text = "${startText}-$accountNo"
        }
        if (TextUtils.isEmpty(mCurTradeNo)) {
            mTvCurAccountInfo.text = "Demo-"
        }
        //更新当前账号的资金信息
        if (!TextUtils.isEmpty(mCurTradeNo)) {
            requestTradeData(mCurTradeType)
            requestFloatSurplus(mCurTradeType)
        }
    }

    /**
     * 未开户的用户跳转到开户引导页
     */
    private fun gotoGuideCreateAccount(userInfo: SystemUserInfo) {
        val isIB = UserType.IB.type == userInfo.type
        if (!isIB) {
            if (userInfo.status < UserStatus.USER_WAITTING.status) {
                GuideCreateAccountActivity.startThis(mContext, userInfo.status, false)
            }
        } else {
            if (!userInfo.hasAccount && !userInfo.hasAudit && userInfo.hasAuditMain == -1) {
                GuideCreateAccountActivity.startThis(mContext, userInfo.status, true)
            }
        }
    }

    override fun onUpdate(obj: Any?) {
        if (obj is Int) {
            if (obj == GlobalInfoManager.UPDATE_DEMO_LIST) {
                val userToken = GlobalInfoManager.getInstance().getUserToken()
                mAccountPresenter.getUserDemoAccountList(userToken)
            } else if (obj == GlobalInfoManager.UPDATE_LIVE_LIST) {
                val userToken = GlobalInfoManager.getInstance().getUserToken()
                mAccountPresenter.getUserLiveAccountList(userToken)
            } else if (obj == GlobalInfoManager.UPDATE_USR_INFO) {
                loadUserInfo()
            }
        }
    }

    override fun onDestroy() {
        mIsActive = false
        GlobalInfoManager.getInstance().remove(this)
        super.onDestroy()
    }
}